package com.liushunqiu.realtor;

import io.vertx.config.ConfigRetriever;
import io.vertx.config.ConfigRetrieverOptions;
import io.vertx.config.ConfigStoreOptions;
import io.vertx.core.AbstractVerticle;
import io.vertx.core.Vertx;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.web.Router;
import io.vertx.ext.web.handler.BodyHandler;
import io.vertx.ext.web.handler.LoggerFormat;
import io.vertx.ext.web.handler.LoggerHandler;
import lombok.extern.slf4j.Slf4j;


/**
 * 入口方法
 */
@Slf4j
public class VertxApplication extends AbstractVerticle {
    /**
     * 默认配置
     */
    private static final String CONFIG_FILE_PATH = "application.yml";

    public static void run(Class className) {
        Vertx vertx = Vertx.vertx();
        Router router = setupRouter(vertx, className);
        loadConfigAndStartServer(vertx, router);
    }

    private static Router setupRouter(Vertx vertx, Class className) {
        Router router = Router.router(vertx);
        router.route().handler(LoggerHandler.create(LoggerFormat.TINY));
        router.route().handler(BodyHandler.create());
        ControllerScanner.create(className.getPackage().getName()).registerControllers(router);
        router.route().failureHandler(ExceptionHandler.create());
        return router;
    }


    private static void loadConfigAndStartServer(Vertx vertx, Router router) {
        ConfigStoreOptions fileStore = new ConfigStoreOptions()
                .setType("yaml")
                .setConfig(new JsonObject().put("path", CONFIG_FILE_PATH));
        ConfigRetrieverOptions options = new ConfigRetrieverOptions().addStore(fileStore);
        ConfigRetriever retriever = ConfigRetriever.create(vertx, options);
        retriever.getConfig(ar -> {
            if (ar.succeeded()) {
                JsonObject config = ar.result();
                int port = config.getJsonObject("server").getInteger("port");
                startServer(vertx, router, port);
            } else {
                log.error("当前项目缺少配置文件:{}", CONFIG_FILE_PATH, ar.cause());
            }
        });
    }

    private static void startServer(Vertx vertx, Router router, Integer port) {
        vertx.createHttpServer()
                .requestHandler(router)
                .listen(port, listenResult -> {
                    if (listenResult.succeeded()) {
                        log.info("项目启动成功，监听端口:{}", port);
                    } else {
                        log.error("项目启动失败", listenResult.cause());
                    }
                });
    }

}
